# -*- coding: UTF-8 -*-

import random
import json

from urllib.request import build_opener, HTTPCookieProcessor, Request
from http.cookiejar import CookieJar
import io


def encode_data(data):
    try:
        return bytes(data, 'utf-8')
    except:
        return bytes(data)


def decode_data(data):
    return io.StringIO(data.read().decode('utf-8'))


class Proxy(object):
    _sid = None

    def __init__(self, baseURL=None, timeout=None, opener=None):
        self.baseURL = baseURL
        self.timeout = timeout
        self._opener = opener
        if not opener:
            cookie_jar = CookieJar()
            self._opener = build_opener(HTTPCookieProcessor(cookie_jar))

    def _get_full_url(self, url):
        return '/'.join([self.baseURL, url])


class ProxyJSON(Proxy):
    def __init__(self, baseURL=None, timeout=None, opener=None):
        super().__init__(baseURL=baseURL, timeout=timeout, opener=opener)

    def __call__(self, url, params=None):
        if params is None:
            params = {}
        data = {
            "jsonrpc": "2.0",
            "method": "call",
            "params": params,
            "id": random.randint(0, 1000000000),
        }

        if url.startswith('/'):
            url = url[1:]
        full_url = self._get_full_url(url)

        data_json = json.dumps(data)

        request = Request(url=full_url, data=encode_data(data_json))
        request.add_header('Content-Type', 'application/json')

        session_id = Proxy._sid
        if session_id:
            request.add_header('X-Openerp-Session-Id', session_id)

        response = self._opener.open(request, timeout=self.timeout)
        data = json.load(decode_data(response))

        url_auth = 'web/session/authenticate'
        # url_info = 'web/session/get_session_info'

        if url in [url_auth]:
            # print('url', url)
            headers = response.headers
            # print('headers', headers)
            cookie = headers['Set-Cookie']
            session_id = cookie[11:51]
            Proxy._sid = session_id
        return data


class JsonRequest(object):
    def __init__(self, baseURL=None, timeout=None):
        self.baseURL = baseURL
        self.timeout = timeout

    def json_call(self, url, **kwargs):
        baseURL = self.baseURL
        timeout = self.timeout
        req = ProxyJSON(baseURL=baseURL, timeout=timeout)
        data = req(url, kwargs)

        error = data.get('error')
        result = data.get('result')

        if error:
            raise Exception(error)

        return result
